#include <callback_event.hpp>
//  ssh 的实现
#ifdef SSH_MODEL_PROXY
    CallbackInterface* CallbackEvent::interface = new CallbackInterface();
#endif

#ifdef SSH_MODEL_LOCAL
#endif

/**
 * 服务端回调
 */
int CallbackEvent::event_auth_password_function(ssh_session session, const char *user, const char *password, void *userdata)
{
    return interface->event_auth_password_function(session, user, password, userdata);
}

ssh_channel CallbackEvent::event_channel_open_request_session_function(ssh_session session, void *userdata)
{
    return interface->event_channel_open_request_session_function(session, userdata);
}

int CallbackEvent::event_auth_pubkey(ssh_session session, const char *user, struct ssh_key_struct *pubkey,
                               char signature_state, void *userdata)
{
    return interface->event_auth_pubkey( session, user, pubkey, signature_state,  userdata);
}

/**
 * 客户端回调
 */
int CallbackEvent::event_channel_data_callback(ssh_session session, ssh_channel channel, void *data, uint32_t len, int is_stderr, void *userdata)
{
    return interface->event_channel_data_callback( session,  channel,data,  len,  is_stderr, userdata);
}

int CallbackEvent::event_channel_exec_request_callback(ssh_session session, ssh_channel channel, const char *command, void *userdata){
    return interface->event_channel_exec_request_callback(session, channel, command, userdata);
}

int CallbackEvent::event_channel_pty_request_callback(ssh_session session, ssh_channel channel, 
                    const char *term, int width, int height, int pxwidth, int pwheight, void *userdata)
{
     return interface->event_channel_pty_request_callback(session, channel, term, width, height, pxwidth, pwheight, userdata);
}

int CallbackEvent::event_channel_pty_window_change_callback(ssh_session session, ssh_channel channel, int width, int height,
                         int pxwidth, int pwheight, void *userdata)
{
    return interface->event_channel_pty_window_change_callback(session, channel, width, height, pxwidth, pwheight, userdata);
}

int CallbackEvent::event_channel_subsystem_request_callback(ssh_session session,ssh_channel channel,const char *subsystem,void *userdata){
    return interface->event_channel_subsystem_request_callback(session, channel, subsystem, userdata);
}

int CallbackEvent::event_channel_shell_request_callback(ssh_session session, ssh_channel channel, void *userdata){
    return interface->event_channel_shell_request_callback(session, channel,  userdata);
}

CallbackEvent::CallbackEvent(void *udata) : server_callbacks(new ssh_server_callbacks_struct()),
                                            channel_callback(new ssh_channel_callbacks_struct())
{
    // 服务端回调
    server_callbacks->userdata = udata;
    server_callbacks->auth_password_function = event_auth_password_function;
    server_callbacks->channel_open_request_session_function = event_channel_open_request_session_function;
    server_callbacks->auth_pubkey_function = event_auth_pubkey;
    // 客户端回调
    channel_callback->userdata = udata;
    channel_callback->channel_data_function = event_channel_data_callback;
    channel_callback->channel_exec_request_function = event_channel_exec_request_callback;
    channel_callback->channel_pty_request_function = event_channel_pty_request_callback;
    channel_callback->channel_pty_window_change_function = event_channel_pty_window_change_callback;
    channel_callback->channel_subsystem_request_function = event_channel_subsystem_request_callback;
    channel_callback->channel_shell_request_function = event_channel_shell_request_callback;
    ssh_callbacks_init(server_callbacks);
    ssh_callbacks_init(channel_callback);
}

CallbackEvent::~CallbackEvent()
{
    if (server_callbacks != nullptr)
    {
        ssh_server_callbacks cb = server_callbacks;
        server_callbacks = nullptr;
        delete (cb);
    }
    if (channel_callback != nullptr)
    {
        ssh_channel_callbacks cb = channel_callback;
        channel_callback = nullptr;
        delete (cb);
    }
}

bool CallbackEvent::set_server_callback(ssh_session session)
{
    return (ssh_set_server_callbacks(session, server_callbacks) == SSH_OK);
}

bool CallbackEvent::set_channel_callback(ssh_channel channel)
{
    return (ssh_set_channel_callbacks(channel, channel_callback) == SSH_OK);
}